#pragma once

#include <string>

class ToString {
public:
	virtual std::string toString() const = 0;
};

enum class Species { DOG = 0, CAT, TIGER, ELEPHANT, SPECIES_NUM, UNKNOWN };

constexpr const char *g_SpeciesName[static_cast<int>(Species::SPECIES_NUM)] = {
	"Dog", "Cat", "Tiger", "Elephant"};

class Animal : public ToString {
protected:
	int age;
	std::string name;
	Species species;

public:
	virtual std::string say() = 0;

public:
	Animal(Species species = Species::UNKNOWN);

	Animal(Species species, const std::string &name, int age);
	std::string toString() const override;

	void setSpecies(Species species);
	std::string getSpeciesName();
	Species getSpeciesId() const;
	void setAge(int age);
	int getAge() const;
	void setName(const std::string &name);
	std::string getName() const;
};

class Dog : public Animal {
public:
	Dog();
	Dog(const std::string &name, int age);
	std::string say() override;
};

class Cat : public Animal {
public:
	Cat();
	Cat(const std::string &name, int age);
	std::string say() override;
};
